package ecom.shell;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import shell.Shell;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

import ecom.entity.CommandeRemote;
import ecom.entity.AccountRemote;
import ecom.ejb.CustomerRemote;
import ecom.ejb.EuroConverterRemote;
import ecom.ejb.EuroConverterRemote.Devise;
import ecom.entity.LigneRemote;
import ecom.entity.ProductStoreRemote;
import ecom.entity.ProductRemote;

/**
 * 
 * @author François haurit
 * @version 1.0
 */
public abstract class Output {

    public static final Document getNewDocument()
	    throws ParserConfigurationException {
	Document retour = null;

	retour = DocumentBuilderFactory.newInstance().newDocumentBuilder()
		.newDocument();

	return retour;
    }

    public static final String toString(final Document document)
	    throws IOException {
	String retour = null;

	OutputFormat format = new OutputFormat(document);
	format.setLineWidth(65);
	format.setIndenting(true);
	format.setIndent(3);
	Writer out = new StringWriter();
	XMLSerializer serializer = new XMLSerializer(out, format);
	serializer.serialize(document);
	retour = out.toString();

	return retour;
    }

    public static final String toString(final ProductRemote product,
	    final Devise dev, final EuroConverterRemote converter) {
	StringBuilder retour = new StringBuilder();

	retour.append("Produit [reference=" + product.getReference()
		+ ", libelle=" + product.getName() + ", prix="
		+ converter.convertFromEuro(product.getPrice(), dev)
		+ ", magasin=" + product.getProductStore().getReference() + "]");

	return retour.toString();
    }

    public static final String toString(final ProductStoreRemote magasin,
	    final Devise dev, final EuroConverterRemote converter) {
	/*
	 * Vartiable de sortie
	 */
	StringBuilder retour = new StringBuilder();

	retour.append("Magasin [reference=" + magasin.getReference() + ", nom="
		+ magasin.getName() + ", compte=" + magasin.getAccount().getIban() 
                + ", produits= {");

	if (magasin.getProducts() != null) {
	    for (ProductRemote produit : magasin.getProducts()) {
		retour.append(Output.toString(produit, dev, converter));
		retour.append(", ");
	    }
	}

	retour.append("} ]");

	/*
	 * Sortie
	 */
	return retour.toString();
    }

    public static final String toString(final CommandeRemote commande,
	    final Devise dev, final EuroConverterRemote converter) {
	/*
	 * Vartiable de sortie
	 */
	StringBuilder retour = new StringBuilder();

	retour.append("Commande [id=" + commande.getId() + ", date="
		+ commande.getDate() + ", montant="
		+ converter.convertFromEuro(commande.getMontant(), dev)
		+ ", compte=" + commande.getCompte().getIban() + ", lignes= {");

	if (commande.getLignes() != null) {
	    for (LigneRemote ligne : commande.getLignes()) {
		retour.append(Output.toString(ligne.getProduct(), dev,
			converter));
		retour.append(", ");
	    }
	}

	retour.append("} ]");

	/*
	 * Sortie
	 */
	return retour.toString();
    }

    public static final String toString(final AccountRemote compte,
	    final Devise dev, final EuroConverterRemote converter) {
	StringBuilder retour = new StringBuilder();

	retour.append("Compte [iban=" + compte.getIban() + ", solde="
		+ converter.convertFromEuro(compte.getSolde(), dev)
		//+ compte.getSolde()
		+ ", identifiant=" + compte.getId() + ", commandes= {");

	if (compte.getCommandes() != null) {
	    for (CommandeRemote commande : compte.getCommandes()) {
		retour.append(Output.toString(commande, dev, converter));
		retour.append(", ");
	    }
	}

	retour.append("} ]");

	return retour.toString();
    }

    public static final String toStringCaddie(
	    final CustomerRemote customer, final Devise dev,
	    final EuroConverterRemote converter) {
	StringBuilder retour = new StringBuilder();

	retour.append("Statut : " + customer.getStatutCart()
		+ Shell.RETOUR_CHARIOT);

	if (customer.getProduitsCart() != null) {
	    retour.append("Affichage du contenu" + Shell.RETOUR_CHARIOT);

	    LigneRemote lr = null;
	    Iterator<LigneRemote> it = customer.getProduitsCart().iterator();
	    while (it.hasNext()) {
		lr = it.next();
		retour.append("\t"
			+ Output.toString(lr.getProduct(), dev, converter)
			+ Shell.RETOUR_CHARIOT);
	    }

	    retour.append("Total : "
		    + converter.convertFromEuro(customer.getMontantCart(),
			    dev) + Shell.RETOUR_CHARIOT);
	} else {
	    retour.append("Caddie vide" + Shell.RETOUR_CHARIOT);
	}

	return retour.toString();
    }

    public static final Element toXml(final ProductRemote product,
	    final Document document, final Devise dev,
	    final EuroConverterRemote converter) {
	/*
	 * Variable de sortie
	 */
	Element retour = null;

	/*
	 * Création d'un élément
	 */
	retour = document.createElement("produit");

	/*
	 * Valorisation des attributs
	 */
	retour.setAttribute("reference", Long.toString(product.getReference()));
	retour.setAttribute("libelle", product.getName());
	retour.setAttribute("prix", Double.toString(converter.convertFromEuro(
		product.getPrice(), dev)));
	retour.setAttribute("magasin",
		Double.toString(product.getProductStore().getReference()));
	retour.setAttribute("urlImage", product.getUrlImage());

	/*
	 * Sortie
	 */
	return retour;
    }

    public static final Element toXml(final AccountRemote compte,
	    final Document document, final Devise dev,
	    final EuroConverterRemote converter) {
	/*
	 * Variable de sortie
	 */
	Element retour = null;

	/*
	 * Création d'un élément
	 */
	retour = document.createElement("compte");

	/*
	 * Valorisation des attributs
	 */
	retour.setAttribute("iban", compte.getIban());
	retour.setAttribute("solde", Double.toString(converter.convertFromEuro(
		compte.getSolde(), dev)));
	retour.setAttribute("identifiant", compte.getId());

	/*
	 * Ajout des commandes
	 */
	for (CommandeRemote commande : compte.getCommandes()) {
	    retour.appendChild(toXml(commande, document, dev, converter));
	}

	/*
	 * Sortie
	 */
	return retour;
    }

    public static final Element toXml(final CommandeRemote commande,
	    final Document document, final Devise dev,
	    final EuroConverterRemote converter) {
	/*
	 * Variable de sortie
	 */
	Element retour = null;

	/*
	 * Création d'un élément
	 */
	retour = document.createElement("commande");

	/*
	 * Valorisation des attributs
	 */
	retour.setAttribute("id", Long.toString(commande.getId()));
	retour.setAttribute("date", commande.getDate().toString());
	retour.setAttribute("montant", Double.toString(converter
		.convertFromEuro(commande.getMontant(), dev)));
	retour.setAttribute("compte", commande.getCompte().getIban());

	/*
	 * Alimentation des produits
	 */
	for (LigneRemote ligne : commande.getLignes()) {
	    /*
	     * Ajout de l'élément fils
	     */
	    retour.appendChild(toXml(ligne.getProduct(), document, dev,
		    converter));
	}

	/*
	 * Sortie
	 */
	return retour;
    }

    public static final Element toXmlCaddie(final CustomerRemote customer,
	    final Document document, final Devise dev,
	    final EuroConverterRemote converter) {
	Element retour = null;
	retour = document.createElement("caddie");

	retour.setAttribute("statut", customer.getStatutCart().toString());
	retour.setAttribute(
		"montant",
		Double.toString(converter.convertFromEuro(
			customer.getMontantCart(), dev)));
	if (customer.getProduitsCart() != null) {

	    for (LigneRemote ligne : customer.getProduitsCart()) {

		retour.appendChild(toXml(ligne.getProduct(), document, dev,
			converter));
	    }
	}

	/*
	 * Sortie
	 */
	return retour;
    }
    
    public static final Element toXml(final ProductStoreRemote magasin,
	    final Document document, final Devise dev,
	    final EuroConverterRemote converter) {
	/*
	 * Variable de sortie
	 */
	Element retour = null;

	/*
	 * Création d'un élément
	 */
	retour = document.createElement("magasin");

	/*
	 * Valorisation des attributs
	 */
	retour.setAttribute("reference", Long.toString(magasin.getReference()));
	retour.setAttribute("nom", magasin.getName());
	retour.setAttribute("compte", magasin.getAccount().getIban());

	/*
	 * Alimentation des produits
	 */
	for (ProductRemote produit : magasin.getProducts()) {
	    /*
	     * Ajout de l'élément fils
	     */
	    retour.appendChild(toXml(produit, document, dev, converter));
	}

	/*
	 * Sortie
	 */
	return retour;
    }
}
